﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace ColorTools {
    public partial class HueSatMapControl : UserControl {
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public event EventHandler<HueSatChangeArgs> HueSatChange;
        private readonly Image _crossHairsImage;
        private bool _hueSatMapMouseDown = false;
        private int _hue;
        private int _sat;

        public HueSatMapControl() {
            InitializeComponent();
            _crossHairsImage = new Bitmap(GetType().Assembly.GetManifestResourceStream("ColorTools.CrossHairs.bmp"));
        }

        public int Hue {
            get { return _hue; }
            set { _hue = value; Refresh(); }
        }

        public int Sat {
            get { return _sat; }
            set { _sat = value; Refresh(); }
        }

        private void HueSatMapControl_Paint(object sender, PaintEventArgs e) {
            if (!_hueSatMapMouseDown) {
                ImageAttributes imgAttrs = new ImageAttributes();
                imgAttrs.SetColorKey(Color.White, Color.White);
                int x = Hue * ClientSize.Width / DevColor.HLSMAX;
                int y = Sat * ClientSize.Height / DevColor.HLSMAX;
                y = ClientSize.Height - y;
                x -= _crossHairsImage.Width / 2;
                y -= _crossHairsImage.Height / 2;
                Rectangle destRect = new Rectangle(x, y, _crossHairsImage.Width, _crossHairsImage.Height);
                e.Graphics.DrawImage(_crossHairsImage, destRect, 0, 0, _crossHairsImage.Width, _crossHairsImage.Height,
                                     GraphicsUnit.Pixel, imgAttrs);
            }
        }

        private void GetHueSatFromHueSatMapXY(int x, int y, out int hue, out int sat) {
            hue = x * DevColor.HLSMAX / ClientSize.Width;
            sat = (ClientSize.Height - y) * DevColor.HLSMAX / ClientSize.Height;
        }

        private void ProcessHueSatMapMouseMove(int x, int y) {
            _hueSatMapMouseDown = true;
            try {
                int hue, sat;
                GetHueSatFromHueSatMapXY(x, y, out hue, out sat);
                _hue = hue;
                _sat = sat;
                HueSatChange(this, new HueSatChangeArgs(hue, sat));
                Refresh();
            }
            finally {
                _hueSatMapMouseDown = false;
            }
        }

        private void HueSatMapControl_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ProcessHueSatMapMouseMove(e.X, e.Y);
            }
        }

        private void HueSatMapControl_MouseDown(object sender, MouseEventArgs e) {
            ProcessHueSatMapMouseMove(e.X, e.Y);
        }

        private void HueSatMapControl_MouseUp(object sender, MouseEventArgs e) {
            Refresh();
        }

        public void SetHueSat(int hue, int sat) {
            _hue = hue;
            _sat = sat;
            Refresh();
        }
    }

    public class HueSatChangeArgs : EventArgs {
        private readonly int _hue;
        private readonly int _sat;

        public HueSatChangeArgs(int hue, int sat) {
            _hue = hue;
            _sat = sat;
        }

        public int Hue {
            get { return _hue; }
        }

        public int Sat {
            get { return _sat; }
        }
    }
}